# conda install conda-forge::selenium  4.16
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.common import exceptions


# 官方文档 https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/first_script/
# 故障和错误排除  https://www.selenium.dev/zh-cn/documentation/webdriver/troubleshooting/
# 隐式等待
# driver.implicitly_wait(0.5)
# 显式等待
# wait = WebDriverWait(driver, timeout=2)
# wait.until(lambda d: revealed.is_displayed())
# 定制 Wait 类，可能包括：
# 更改评估代码的频率（轮询间隔）
# 指定应自动处理的异常
# 更改总超时长度
# 自定义超时消息
# errors = [NoSuchElementException, ElementNotInteractableException]
# wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
# wait.until(lambda d: revealed.send_keys("Displayed") or True)


# 通过 xpath 判断元素是否存在
def is_element_present(driver, by, value):
    try:
        driver.find_element(by, value)
        return True
    except exceptions.NoSuchElementException:
        return False


def example():
    options = Options()
    options.binary_location = "chrome-linux_114.0.5726.0/chrome"
    service = Service("chromedriver_114.0.5735.90")
    with webdriver.Chrome(options=options, service=service) as driver:
        driver.delete_all_cookies()
        driver.implicitly_wait(0.5)
        driver.maximize_window()
        driver.get("https://www.baidu.com")
        print(driver.title)
        print(driver.current_url)
        print(driver.get_cookies())
        driver.save_screenshot("./baidu.png")
        input("按任意键退出...")


if __name__ == "__main__":
    example()

#  交互
# print(title=driver.title)
# print(url=driver.current_url)
# 导航
# driver.get("http://www.baidu.com'")
# driver.back()
# driver.forward()
# driver.refresh()

# Alerts 警告框
# driver.find_element(By.LINK_TEXT, "警告xxx!").click()
# alert = wait.until(expected_conditions.alert_is_present())
# print(text = alert.text)
# alert.accept()

# Confirm 确认框
# driver.find_element(By.LINK_TEXT, "确定xxx吗?").click()
# wait.until(expected_conditions.alert_is_present())
# alert = driver.switch_to.alert
# print(text = alert.text)
# alert.dismiss()

# 添加Cookie
# driver.add_cookie({"name": "test1", "value": "cookie1"})
# driver.add_cookie({"name": "test2", "value": "cookie2"})
# print(driver.get_cookie("test1"))
# print(driver.get_cookies())
# 删除Cookie
# driver.delete_cookie("test1")
# print(driver.get_cookies())
# driver.delete_all_cookies()
# print(driver.get_cookies())
# Same-Site Cookie属性
# 此属性允许用户引导浏览器控制cookie, 是否与第三方站点发起的请求一起发送. 引入其是为了防止CSRF（跨站请求伪造）攻击.
# 当sameSite属性设置为 Strict, cookie不会与来自第三方网站的请求一起发送.
# 当您将cookie sameSite属性设置为 Lax, cookie将与第三方网站发起的GET请求一起发送.
# driver.add_cookie({"name": "foo", "value": "value", 'sameSite': 'Strict'})
# driver.add_cookie({"name": "foo1", "value": "value", 'sameSite': 'Lax'})

# 使用cookie登录，使用到一个chrome插件
# EditThisCookie 导出功能，
# 当你登录完淘宝后点击导出便会得到一个list格式的字符串
# for item in cookies:
#     driver.add_cookie(item)

#  使用 iframe 可能会得到一个 no such element 无此元素 的错误。 这是因为 Selenium 只知道顶层文档中的元素。
#  需要首先切换到框架， 这与切换窗口的方式类似。WebDriver 提供了三种切换到frame的方法。
# https://www.selenium.dev/zh-cn/documentation/webdriver/interactions/frames/


# 关闭标签页或窗口
# driver.close()
# 切回到之前的标签页或窗口
# driver.switch_to.window(original_window)

# 彻底释放资源
# 当你完成了浏览器会话，你应该调用 quit 退出，而不是 close 关闭！！！
# 关闭所有与 WebDriver 会话相关的窗口和选项卡
# 结束浏览器进程
# 结束后台驱动进程
# 通知 Selenium Grid 浏览器不再使用，以便可以由另一个会话使用它(如果您正在使用 Selenium Grid)
# quit() 失败将留下额外的后台进程和端口运行在机器上，这可能在以后导致一些问题。
# 使用 with 关键字时，可以在执行结束时自动退出驱动程序。
# with webdriver.Firefox() as driver:

# 屏幕截图
# Returns and base64 encoded string into image
# driver.save_screenshot('./image.png')
# 元素屏幕截图
# ele = driver.find_element(By.CSS_SELECTOR, 'h1')
# ele.screenshot('./image.png')

# 在当前frame或者窗口的上下文中，执行JavaScript脚本
# header = driver.find_element(By.CSS_SELECTOR, "h1")
# driver.execute_script('return arguments[0].innerText', header)

# 键鼠操作
# clickable = driver.find_element(By.ID, "clickable")
# ActionChains(driver)
# .move_to_element(clickable)
# .pause(1)
# .click_and_hold()
# .pause(1)
# .send_keys("abc")
# .perform()
# 释放所有Actions
# ActionBuilder(driver).clear_actions()

# 查找元素，可以使用浏览器的 copy xpath
#     driver.find_element(By.XPATH, "//input[@value='f']")
# fruits = driver.find_element(By.ID, "fruits")
# fruits = driver.find_element(By.NAME, "fruits")
# fruit = fruits.find_element(By.CLASS_NAME, "tomatoes")
# fruit = driver.find_element(By.CSS_SELECTOR,"#fruits .tomatoes")
# plants = driver.find_elements(By.TAG_NAME, "li")
# plants = driver.find_elements(By.LINK_TEXT, "li")
# plants = driver.find_elements(By.PARTIAL_LINK_TEXT, "li")
